package com.shopping.huaju.commodity.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shopping.huaju.commodity.dao.AttrAttrgroupRelationDao;
import com.shopping.huaju.commodity.dao.AttrgroupDao;
import com.shopping.huaju.commodity.dao.CategoryDao;
import com.shopping.huaju.commodity.entity.AttrAttrgroupRelationEntity;
import com.shopping.huaju.commodity.entity.AttrgroupEntity;
import com.shopping.huaju.commodity.entity.CategoryEntity;
import com.shopping.huaju.commodity.entity.vo.BaseAttrRespVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shopping.huaju.common.utils.PageUtils;
import com.shopping.huaju.common.utils.Query;

import com.shopping.huaju.commodity.dao.AttrDao;
import com.shopping.huaju.commodity.entity.AttrEntity;
import com.shopping.huaju.commodity.service.AttrService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Resource
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    @Resource
    private AttrgroupDao attrgroupDao;
    @Resource
    private CategoryDao categoryDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 实现将区分基本属性和销售属性，将销售属性入属性库，将基本属性入属性库，同时还要记录属性和属性组的关联关系到关系库
     * 该方法 涉及操作多张表，需要开启声明式事务
     * @param attr
     * @return
     */
    @Override
    @Transactional
    public boolean saveAttrAndAttrGroupRelation(AttrEntity attr) {
        //无论是 销售属性还是基本属性 保存到属性库
        this.save(attr);
        //判断是销售属性还是基本属性
        if(attr.getAttrType() == 1 && attr.getAttrGroupId() != null){    //如果是基本属性，需要多一步记录属性和属性组的关联关系到关系库
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            //这里排序默认设置为0
            attrAttrgroupRelationEntity.setAttrSort(0);
            attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
        }
        return true;
    }

    @Override
    public boolean updateAttrAndAttrGroupRelation(AttrEntity attr) {
        if(attr.getAttrType() == 1 && attr.getAttrGroupId() != null){    //如果是基本属性，需要多一步记录属性和属性组的关联关系到关系库
            Map<String, Object> map = new HashMap<>();
            map.put("attr_id",attr.getAttrId());
            List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationDao.selectByMap(map);
            if(!relationEntities.isEmpty()){    //如果属性关联存在 -- 一个基本属性只会属于一个属性组
                //则修改属性属性组关联关系
                AttrAttrgroupRelationEntity entity = relationEntities.get(0);
                entity.setAttrGroupId(attr.getAttrGroupId());
                attrAttrgroupRelationDao.updateById(entity);
            }else {
                //如果属性组不存在  //添加入库
                AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
                attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());
                attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
                //这里排序默认设置为0
                attrAttrgroupRelationEntity.setAttrSort(0);
                attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
            }
        }
        this.updateById(attr);
        return true;
    }

    @Override
    public PageUtils queryPageBaseAttr(Map<String, Object> params, Long categoryId) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> {
            wrapper.eq("attr_type",1);
        });
        String key = (String) params.get("key");
        if(StringUtils.isNotBlank(key)){    //如果携带查询条件
            queryWrapper.and(wrapper -> {
                wrapper.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        if(categoryId!=null && categoryId != 0L){   //如果携带categoryId 条件
            queryWrapper.eq("category_id",categoryId);
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> records = page.getRecords();
        if(records == null || records.isEmpty()){
            return new PageUtils(page);
        }
        List<BaseAttrRespVo> baseAttrRespVos = records.stream().map((entity) -> {
            BaseAttrRespVo baseAttrRespVo = new BaseAttrRespVo();
            BeanUtils.copyProperties(entity, baseAttrRespVo);
            CategoryEntity categoryEntity = categoryDao.selectById(entity.getCategoryId());
            baseAttrRespVo.setCategoryName(categoryEntity.getName());
            return baseAttrRespVo;
        }).collect(Collectors.toList());
        pageUtils.setList(baseAttrRespVos);
        return pageUtils;
    }

    @Override
    public PageUtils queryPageSaleAttr(Map<String, Object> params, Long categoryId) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> {
            wrapper.eq("attr_type",0);
        });
        String key = (String) params.get("key");
        if(StringUtils.isNotBlank(key)){    //如果携带查询条件
            queryWrapper.and(wrapper -> {
                wrapper.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        if(categoryId!=null && categoryId != 0L){   //如果携带categoryId 条件
            queryWrapper.eq("category_id",categoryId);
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {
        // 1. 根据 attrGroupId 到 属性和属性组关系表中获取 所有的 attr_group_Relation 对象
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities =
                attrAttrgroupRelationDao.selectList(
                        new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId)
                );
        // 2. 使用流式计算将所有关系对象中的属性id 进行收集
        List<Long> attrIds = attrAttrgroupRelationEntities.stream().map(item -> item.getAttrId()).collect(Collectors.toList());
        //3. 如果 attrIds 集合中没有属性id 则说明该属性组暂未拥有对应的属性，直接返回null
        if (attrIds.isEmpty()){
            return null;
        }
        //4. 有属性，则通过属性id获取属性对象
        List<AttrEntity> attrEntities = this.listByIds(attrIds);
        //5. 将获得的对象返回
        return attrEntities;
    }

    //实现根据属性组id返回对应可以添加的基本属性的信息列表
    @Override
    public PageUtils getAllowedAttrs(Map<String, Object> params,Long attrGroupId) {

        //1. 根据属性组id返回 对应的分类id
        AttrgroupEntity attrgroupEntity = attrgroupDao.selectById(attrGroupId);
        Long categoryId = attrgroupEntity.getCategoryId();
        //2. 根据分类id 获取 该分类下的所有属性组
        List<AttrgroupEntity> attrgroupEntities =
                attrgroupDao.selectList(new QueryWrapper<AttrgroupEntity>().eq("category_id", categoryId));
        //3. 使用流式计算，获取 将属性组列表中的属性组id获取出来
        List<Long> attrgroupIds = attrgroupEntities.stream().map(item -> item.getId()).collect(Collectors.toList());
        //4. 获取关联关系表中，与 属性组列表 相关联的 关系对象 即这些对象是与该分类下的属性组进行关联了，属于不允许关联对象
        if (attrgroupIds != null && !attrgroupIds.isEmpty()) {  //虽然肯定不为空，但是还是进行校验一下
            List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationDao.selectList(
                    new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", attrgroupIds));
            //5. 使用流式计算，获取 将关系对象列表中的属性id获取出来, 这些 属性id 就是不满足要求的属性
            List<Long> disallowedAttrIds =
                    attrAttrgroupRelationEntities.stream().map(item -> item.getAttrId()).collect(Collectors.toList());
            //6. 创建 属性条件选择器，
            QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>();
            if(!disallowedAttrIds.isEmpty()){
                //7. 第一个筛选条件 - attrId 不能在 disallowedAttrIds中
                queryWrapper.notIn("attr_id",disallowedAttrIds);
            }
            //如果 没有不满足要求的属性 即 disallowedAttrIds 为空集合
            //则第一个筛选条件不需要
            //8. 第二个筛选条件 - category_id 必须等于传进来的属性组id对应的分类id，同时必须是基本属性
            queryWrapper.eq("category_id",categoryId);
            queryWrapper.eq("attr_type",1);
            //9. 第三个筛选条件 - 前端带进来的key条件
            String key = (String) params.get("key");
            if(StringUtils.isNotBlank(key)){    //如果有指定查询条件 - 需要加入条件选择器
                queryWrapper.and(wrapper -> {
                    wrapper.eq("attr_id",key).or().like("attr_name",key);
                });
            }
            //10. 条件指定完毕 返回pageUtils对象
            IPage<AttrEntity> page = this.page(
                    new Query<AttrEntity>().getPage(params),
                    queryWrapper
            );
            return new PageUtils(page);
        }
        return null;
    }

    @Override
    public List<Long> selectSearchAttrIds(List<Long> attrIds) {
       return baseMapper.selectSearchAttrIds(attrIds);
    }

}